#define _UARTAPP_GLOBAL_
#include "config.h"

void Uart1DeInit(void)
{
	Uart1_RxEn = 0;
	Uart1_TxEn = 0;

	DMA_DeInit(DMA1_Channel5);
	/* Enable the USART1 Interrupt */
	NVIC_Configuration(USART1_IRQn,USART1_PREPRIORITY,USART1_SUBPRIORITY,DISABLE);

	USART_DeInit(USART1);

	/* Configure USART1 Tx (PA.09) as input floating */
	GPIOA_MODE9=INPUT_MODE;GPIOA_CNF9=IN_FLOATING;
	/* Configure USART1 Rx (PA.10) as input floating */
	GPIOA_MODE10=INPUT_MODE;GPIOA_CNF10=IN_FLOATING;
}

u8 UART1_Rxdata[Uart1RxFifoSize];
u16 uart1HaveRxCnt;

void Uart1Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

///////////////////////DMA
  	DMA_InitTypeDef DMA_InitStructure;
///////////////////////DMA

	GPIOA_MODE9=OUTPUT_MODE_50MHZ;GPIOA_CNF9=OUT_AL_PP;
	/* Configure USART1 Rx (PA.10) as input floating */
	GPIOA_MODE10=INPUT_MODE;GPIOA_CNF10=IN_PP;
	GPIOA_SET=(1<<10);

//	GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);

	FIFO_INIT(Uart1RxFifo);	
	FIFO_INIT(Uart1TxFifo);	
	/* Enable USART1 clocks */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	/* Enable the USART1 Interrupt */
	NVIC_Configuration(USART1_IRQn,USART1_PREPRIORITY,USART1_SUBPRIORITY,ENABLE);

///////////////////////DMA
  /* USARTy TX DMA1 Channel (triggered by USARTy Rx event) Config */
  DMA_DeInit(DMA1_Channel5);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART1_Rxdata;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = Uart1RxFifoSize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
///////////////////////DMA

	/* USART1 configuration ------------------------------------------------------*/
	/* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the USART1 */
	USART_Init(USART1, &USART_InitStructure);
/*
	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(USART1, &USART_ClockinitStructure);
*/
///////////////////////DMA
  USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DMA1_Channel5, ENABLE);
  uart1HaveRxCnt = 0;
///////////////////////DMA
	/* Enable the USART Transmoit interrupt: this interrupt is generated when the 
	USART1 transmit data register is empty */  
//	USART_ITConfig(USART1, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART1 receive data register is not empty */
//	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

	/* Enable USART1 */
	USART_Cmd(USART1, ENABLE);
///////////////////////DMA
  DMA_Cmd(DMA1_Channel5, ENABLE);
///////////////////////DMA
	Uart1_RxEn = 1;
	Uart1_TxEn = 1;
}

void ReadUart1DataUsingDMA(void)
{
	u16	nowHave;
	if (Uart1_RxEn)
	{
		nowHave = Uart1RxFifoSize - DMA_GetCurrDataCounter(DMA1_Channel5);
		if(nowHave >= Uart1RxFifoSize)
		{
			return;
		}
		if(nowHave != uart1HaveRxCnt)
		{
			while(nowHave != uart1HaveRxCnt)
			{
				FIFO_PUT_ONE(Uart1RxFifo,UART1_Rxdata[uart1HaveRxCnt]);
				uart1HaveRxCnt++;
				if(uart1HaveRxCnt == Uart1RxFifoSize)
				{
					uart1HaveRxCnt = 0; 
				}
			}
		}
	}
}
void Uart2DeInit(void)
{
	Uart2_RxEn = 0;
	Uart2_TxEn = 0;
	DMA_DeInit(DMA1_Channel6);
	/* Enable the USART2 Interrupt */
	NVIC_Configuration(USART2_IRQn,USART2_PREPRIORITY,USART2_SUBPRIORITY,DISABLE);

	USART_DeInit(USART2);

#if 1
	GPIOA_MODE3=INPUT_MODE;GPIOA_CNF3=IN_FLOATING;
	GPIOA_MODE2=INPUT_MODE;GPIOA_CNF2=IN_FLOATING;
#else
	/* Configure USART2 Tx (PD.05) as input floating */
	GPIOD_MODE5=INPUT_MODE;GPIOD_CNF5=IN_FLOATING;
	/* Configure USART2 Rx (PD.06) as input floating */
	GPIOD_MODE6=INPUT_MODE;GPIOD_CNF6=IN_FLOATING;
#endif
}

u8 UART2_Rxdata[Uart2RxFifoSize];
u16 uart2HaveRxCnt;

void Uart2Init(u32 baudrate)
{
	USART_InitTypeDef USART_InitStructure;
//	USART_ClockInitTypeDef USART_ClockinitStructure;

///////////////////////DMA
  DMA_InitTypeDef DMA_InitStructure;
///////////////////////DMA

#if 1
	GPIOA_MODE2=OUTPUT_MODE_50MHZ;GPIOA_CNF2=OUT_AL_PP;
	GPIOA_MODE3=INPUT_MODE;GPIOA_CNF3=IN_FLOATING;
#else
	/* Configure USART2 Tx (PD.05) as alternate function push-pull */
	GPIOD_MODE5=OUTPUT_MODE_50MHZ;GPIOD_CNF5=OUT_AL_PP;
	/* Configure USART2 Rx (PD.06) as input floating */
	GPIOD_MODE6=INPUT_MODE;GPIOD_CNF6=IN_FLOATING;

	GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
#endif

	FIFO_INIT(Uart2RxFifo);	
	FIFO_INIT(Uart2TxFifo);	
	/* Enable USART2 clocks */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	/* Enable the USART2 Interrupt */
	NVIC_Configuration(USART2_IRQn,USART2_PREPRIORITY,USART2_SUBPRIORITY,ENABLE);

///////////////////////DMA
  /* USARTy TX DMA1 Channel (triggered by USARTy Rx event) Config */
  DMA_DeInit(DMA1_Channel6);  
  DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART2_Rxdata;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = Uart2RxFifoSize;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);
///////////////////////DMA

	/* USART1 configuration ------------------------------------------------------*/
	/* USART1 configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - Two Stop Bit
        - Odd parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
        - USART Clock disabled
        - USART CPOL: Clock is active low
        - USART CPHA: Data is captured on the second edge 
        - USART LastBit: The clock pulse of the last data bit is not output to 
                         the SCLK pin
	*/
	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	/* Configure the USART2 */
	USART_Init(USART2, &USART_InitStructure);

//	USART_ClockinitStructure.USART_Clock = USART_Clock_Disable;
//	USART_ClockinitStructure.USART_CPOL = USART_CPOL_Low;
//	USART_ClockinitStructure.USART_CPHA = USART_CPHA_2Edge;
//	USART_ClockinitStructure.USART_LastBit = USART_LastBit_Disable;
//	/* Configure the USART2 */
//	USART_ClockInit(USART2, &USART_ClockinitStructure);
///////////////////////DMA
  USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
  DMA_Cmd(DMA1_Channel6, ENABLE);
  uart2HaveRxCnt = 0;
///////////////////////DMA
	/* Enable the USART Transmoit interrupt: this interrupt is generated when the 
	USART2 transmit data register is empty */  
//	USART_ITConfig(USART2, USART_IT_TXE, ENABLE);

	/* Enable the USART Receive interrupt: this interrupt is generated when the 
	USART2 receive data register is not empty */
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

	/* Enable USART2 */
	USART_Cmd(USART2, ENABLE);
///////////////////////DMA
  DMA_Cmd(DMA1_Channel6, ENABLE);
///////////////////////DMA
	Uart2_RxEn = 1;
	Uart2_TxEn = 1;
}

void ReadUart2DataUsingDMA(void)
{
	u16	nowHave;
	if (Uart2_RxEn)
	{
		nowHave = Uart2RxFifoSize - DMA_GetCurrDataCounter(DMA1_Channel6);
		if(nowHave >= Uart2RxFifoSize)
		{
			return;
		}
		if(nowHave != uart2HaveRxCnt)
		{
			while(nowHave != uart2HaveRxCnt)
			{
				FIFO_PUT_ONE(Uart2RxFifo,UART2_Rxdata[uart2HaveRxCnt]);
				uart2HaveRxCnt++;
				if(uart2HaveRxCnt == Uart2RxFifoSize)
				{
					uart2HaveRxCnt = 0; 
				}
			}
		}
	}
}

void UARTRxFreeIdleProc(void)
{
	ReadUart1DataUsingDMA();
	ReadUart2DataUsingDMA();
}

void UARTTxFreeIdleProc(void)
{	
	if(Uart1_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart1TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART1 Transmit interrupt */
			USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
		}
	}
	if(Uart2_TxEn > 0)
	{
		if(FIFO_GET_COUNT(Uart2TxFifo))//if TxBUFR is not EMPTY
		{
			/* Disable the USART2 Transmit interrupt */
			USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
		}
	}
}

